import re

from django_redis import get_redis_connection
from rest_framework import serializers

from goods.models import SKU
from users.models import User, Address


class RegisterCreateSerializer(serializers.ModelSerializer):
    # 校验密码,短信验证码,是否同意协议
    # read_only只用于序列化
    password2=serializers.CharField(label='校验密码',allow_null=False,allow_blank=False,write_only=True)
    # password2=serializers.CharField(label='校验密码',allow_null=False,allow_blank=False)
    sms_code=serializers.CharField(label='短信验证码',max_length=6,min_length=6,allow_null=False,allow_blank=False,write_only=True)
    allow=serializers.CharField(label='是否同意协议',allow_null=False,allow_blank=False,write_only=True)
    token=serializers.CharField(read_only=True)
    class Meta:
        model=User
        fields=('id','username','password','password2','mobile','sms_code','allow','token')
        extra_kwargs={
            'id':{'read_only':True},
            'username':{
                'min_length':5,
                'max_length':20,
                'error_messages':{
                    'min_length': '仅允许5-20个字符的用户名',
                    'max_length':'仅允许5-20个字符的用户名'
                }

            },
            'password': {
                'write_only': True,
                'min_length': 8,
                'max_length': 20,
                'error_messages': {
                    'min_length': '仅允许8-20个字符的密码',
                    'max_length': '仅允许8-20个字符的密码',
                }
            }
        }

        def validate_mobile(self,mobile):
            if not re.match(r'1[3-9]\d{9}',mobile):
                raise serializers.ValidationError('手机号格式不正确')
            return mobile
        def validate_allow(self,value):
            if value!='true':
                raise serializers.ValidationError('您未同意协议')
            return value
        def validate(self,attrs):
            print(attrs)
            password=attrs.get('password')
            password2=attrs.get('password2')
            if password!=password2:
                raise serializers.ValidationError('两次密码不一致')
    #         验证短信验证码
            code=attrs.get('sms_code')
            redis_conn=get_redis_connection('code')
            mobile=attrs.get('mobile')
            sms_code=redis_conn.get('sms_%s'%mobile)
            # 短信验证码过期
            if sms_code is None:
                raise serializers.ValidationError('短信验证码过期啦')
            if code!=sms_code:
                raise serializers.ValidationError('短信验证码不正确')
            return attrs
    def create(self,validated_data):
        del validated_data['password2']
        del validated_data['sms_code']
        del validated_data['allow']
        user=User.objects.create(**validated_data)
        user.set_password(validated_data['password'])
        user.save()
        # 注册完成后自动登录
        # 找到哪里注册完成之后
        # 数据入库后注册完成
        # 生一个token
        from rest_framework_jwt.settings import api_settings

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        # 返回token
        user.token=token
        return user

# 用户中心序列化机器
class UserDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model=User
        fields=('id','username','mobile','email','email_active')
# 邮箱验证序列化器
class  EmailSerializer(serializers.ModelSerializer):
    class Meta:
        model= User
        fields=('email',)
        extra_kwargs={
            'email':{
                'required':True
            }
        }
class UserCenterSerializer(serializers.ModelSerializer):
    class Meta:
        model=User
        fields=('id','username','mobile','email')

class UpdateEmailSerializer(serializers.ModelSerializer):
    class Meta:
        model=User
        fields=('id','email','email_active')
        extra_kwargs={
            'email':{
                'required':True
            }
        }

# 用户地址保存序列化器
class AddressSerializer(serializers.ModelSerializer):
    province = serializers.StringRelatedField(read_only=True)
    city = serializers.StringRelatedField(read_only=True)
    district = serializers.StringRelatedField(read_only=True)
    province_id = serializers.IntegerField(label='省ID', required=True)
    city_id = serializers.IntegerField(label='市ID', required=True)
    district_id = serializers.IntegerField(label='区ID', required=True)
    mobile = serializers.RegexField(label='手机号', regex=r'^1[3-9]\d{9}$')
    class Meta:
        model=Address
        exclude = ('user', 'is_deleted', 'create_time', 'update_time')
    #     [ < users.views.AddressView object at 0x7f484c0bca58 >] (1048, "Column 'user_id' cannot be null")
    # user_id为外键必须传
    def create(self,validated_data):
        # self.context二级视图自动添加
        user=self.context['request'].user
        validated_data['user_id']=user.id
        address=Address.objects.create(**validated_data)
        return address

class TitleAddressSerializer(serializers.ModelSerializer):
    class Meta:
        model=Address
        fields=['title']
# 新增用户浏览记录的序列化器
class AddUserBrowerhistoriesSerializer(serializers.Serializer):
#     sku_id
    sku_id=serializers.IntegerField(label='商品编号',min_value=1,required=True)
    def validate_sku_id(self, sku_id):
        '''
        商品是否存在
        '''
        try:
            SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            raise serializers.ValidationError('商品不存在')
        return sku_id
    def create(self, validated_data):
        '''
        保存user_id和sku_id
        :param validated_data:
        :return:
        '''
        # 上次出现是在新增收获地址
        user_id=self.context['request'].user.id
        sku_id=validated_data['sku_id']
        # 连接redis
        redis_conn = get_redis_connection('history')
        # 移除已经存在的本记录
        redis_conn.lrem('history_%s' % user_id, 0, sku_id)
        # 添加新的记录
        redis_conn.lpush('history_%s' % user_id, sku_id)
        # 保存最多5条记录
        redis_conn.ltrim('history_%s' % user_id, 0, 4)
        return validated_data
class GetUserBrowerhistoriesSerializer(serializers.ModelSerializer):
    class Meta:
        model=SKU
        fields=['id','name','price','default_image_url','comments']





